package com.atguigu.java8.lambda;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

public class TestLambda2 {

    // 语法格式一：无参数，无返回值
    // 	() -> System.out.println("Hello Lambda")
    @Test
    public void test1() {
        int num = 0;
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                // Variable 'num' is accessed from within inner class, needs to be final or effectively final
                // System.out.println("Hello Lambda:" + num++);

                System.out.println("Hello Lambda:" + num);
            }
        };
        runnable.run();

        System.out.println("------------------------");

        Runnable runnable1 = () -> System.out.println("Hello Lambda again");
        runnable1.run();
    }

    // 语法格式二：有一个参数，无返回值
    //  (x) -> System.out.println(x)
    @Test
    public void test2() {
        Consumer<String> consumer = (x) -> System.out.println(x);
        consumer.accept("Hello Lambda");

        // 语法格式三：若只有一个参数，小括号可以省略不写
        Consumer<String> consumer2 = x -> System.out.println("result:" + x);
        consumer2.accept("Hello Lambda again");
    }

    // 语法格式四：有两个以上参数，有返回值，并且Lambda体中有多条语句
    @Test
    public void test3() {
        Comparator<Integer> comparator = (x, y) -> {
            System.out.println("compare int");
            return Integer.compare(x, y);
        };
    }

    // 语法格式五：若Lambda体中只有一条语句，return和大括号都可以省略不写
    @Test
    public void test4() {
        Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);

        // 语法格式六：Lambda表达式的参数列表的数据类型可以省略不写，因为JVM编译器通过上下文可以推断出，数据类型，即“类型推断”
        Comparator<Double> comparator2 = (Double x, Double y) -> Double.compare(x, y);
        Comparator<Double> comparator3 = (x, y) -> -Double.compare(x, y);
    }

    @Test
    public void test5() {
        String[] strings = {"aa", "bb", "cc"};

        String[] strings1;
        // Array initializer is not allowed here, 这里类型推断失败
        // strings1 = {"aa","bb","cc"};
        strings1 = new String[]{"aa", "bb", "cc"};

        // 类型自动推断
        List<String> list = new ArrayList<>();

        // 类型自动推断
        show(new HashMap<>());
    }

    private void show(Map<String, Integer> paramMap) {

    }

    // 需求：对一个数进行运算
    @Test
    public void test6() {
        Integer result = operation(100, x -> x * x);
        System.out.println(result);

        System.out.println("-----------------------");
        System.out.println(operation(200, x -> x + 200));
    }

    private Integer operation(Integer num, MyFun myFun) {
        return myFun.getValue(num);
    }

}
